home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-05 | 12.4 KB | 332 lines | [TEXT/MPS ] |
- (* ---------------------------------------------------------------------
-
- Pascal source for XWindShell XCMD
-
- Copyright © 1989-92 Apple Computer, Inc.
-
-
- This file includes the source code for the XWindShell XCMD. While
- this XCMD will compile and execute in its current form. The XWindow
- has no functionality beyond demonstrating the basics of HyperCard's
- XWindow capabilities. This file is meant to be a basis where an
- XCMD author can "fill in the blanks" to create their XCMD. See the
- other sample XCMDs such as Picture, MemState, and ListWindow for
- practical examples of code dealing with responding to XWindow events
- and strategies for storing information for the XWindows while they
- are open.
-
- The files included with the XWindShell XCMD are meant to be
- used as a starting point for XCMDs in C or Pascal that wish to
- create and manage XWindows.
-
- Files:
- ------
- *XWindShell.p
- XWindShell.r
- MakeFile
-
-
- Author: Darin Acquistapace
- Created: 01/29/92
- Modified: See Mod History Below
-
- Modification History:
- ---------------------
- 01/29/92 - New today.
-
- ------------------------------------------------------------------ *)
-
- UNIT DummyUnit;
-
- {$Z+ }
- {$N+ }
-
- INTERFACE
-
- USES
- Types, Memory, MiscTool, GSOS, QuickDraw, Resources, QDAux, Events,
- Controls, Windows, HyperXCMD;
-
- PROCEDURE EntryPoint(paramPtr: XCMDPtr);
-
- IMPLEMENTATION
-
- PROCEDURE XWindShell(paramPtr: XCMDPtr); FORWARD;
-
- PROCEDURE EntryPoint(paramPtr: XCMDPtr);
- BEGIN
- XWindShell(paramPtr);
- END;
-
- { Any external procedures or functions should be declared here in the form:
- PROCEDURE MyExternalRoutine(inputWord: INTEGER); EXTERNAL;
-
- Additionally, any functions or procedures that need to be accessed from
- the toolbox or GS/OS, such as a custom item control routine, should be
- placed here. }
-
- PROCEDURE XWindShell(paramPtr: XCMDPtr);
- { Definitions of any constants, types, and variables needed by the main
- routine of the XCMD or more than one nested procedure. }
- CONST
- LeftPos = 100; { Window coordinates in 640 coordinates }
- TopPos = 50;
- WindWidth = 250;
- WindHeight = 60;
- WindTitle = 'SampleXWindow';
-
- ScriptErrStr = 'Can''t understand arguments of XCMD XWindShell.';
- CopyrightStr = 'XWindShell XCMD v1.0" & return & "by Darin Acquistapace, 1/29/92" & return & "© 1992 Apple Computer, Inc.';
- HelpStr = 'FORM: XWindShell';
- WrongVersionStr = 'XWindShell XCMD requires HyperCard IIGS 1.1';
- CreateErrStr = 'Unable to create window';
-
- VAR
- memoryID: INTEGER;
- xWindow: WindowPtr;
- windRect: Rect;
- str: Str255;
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE MyDisposeHandle(h: Handle);
- { Checks a handle for NIL before disposing of it. A good practice. }
- BEGIN
- IF h <> NIL THEN DisposeHandle(h);
- END; {MyDisposeHandle}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE ReturnResult(str: Str255);
- { Puts the specified string into the result and terminates. }
- BEGIN
- paramPtr^.returnValue := PasToZero(str);
- EXIT(XWindShell);
- END; {ReturnResult}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HTError;
- { Generates a HyperTalk error dialog box complete with Script and Cancel
- buttons. }
- BEGIN
- paramPtr^.returnStat := 1;
- ReturnResult(ScriptErrStr);
- END; {HTError}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE CommandInfo(str: str255);
- { Puts the specified string into a dialog box and terminates. }
- BEGIN
- SendHCmessage(Concat('answer "', str, '"'));
- EXIT(XWindShell);
- END; {CommandInfo}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE UpdateXWindow(whichWindow: WindowPtr);
- { Handles updating the contents of the XWindow. This may include drawing
- a background picture, calling DrawControls, etc. HyperCard takes care of
- calling BeginUpdate and EndUpdate for you. This routine should only update
- the window. Be careful not to do anything that might cause another update
- event to occur which would result in recursion. }
- BEGIN
- END; {UpdateXWindow}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE CleanUpMemory(whichWindow: WindowPtr);
- { Free all memory associated with the XWindow. This could be a handle
- referenced by the GetXWindowValue callback. }
- BEGIN
- END; {CleanUpMemory}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HandleWindowClick(whichWindow: WindowPtr; ourEvent: EventRecord);
- { A mouseDown event has occurred in our window. This procedure handles
- tracking the click and taking whatever actions are necessary as a result
- of the click. Tracking controls in XWindows is no different than doing
- the same in any standard window. FindControl and TrackControl would be
- commonly used to track the click. See the Picture and ListWindow sample
- XCMDs for examples of using the control manager to handle these actions. }
- BEGIN
- END; {HandleWindowClick}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE ProcessIdle(whichWindow: WindowPtr);
- { Take any actions that need to be performed periodically. This procedure
- will only be called if the SetXWIdleTime callback has been called with
- an interval value other than zero (the default.) }
- BEGIN
- END; {ProcessIdle}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HandleOpenEvent(whichWindow: WindowPtr);
- { Perform any actions necessary before any other events are sent. At this
- point, the window is created and visible. }
- BEGIN
- { Allow reentrancy, if this is not set, the XWindow may lose events that
- occur because of events instigated by the XCMD. For instance, if the
- mouseDown handler performs some action which causes HyperCard to close
- the XWindow, the xCloseEvt will not be received because the XCMD has the
- code in the mouseDown handler pending and will be returned to when Hyper-
- Card finishes executing whatever task the mouseDown handler began. This
- can be set to true for both types of events in most XCMDs and set to false
- temporarily if the need arises to temporarily halt recursive calls to the
- XCMD.
-
- If an XCMD wishes to recieve null events, it should call SetXWIdleTime
- at this point with an interval other than zero.}
- XWAllowReEntrancy(whichWindow, TRUE, TRUE);
- END; {HandleOpenEvent}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HandleCursorWithin(whichWindow: WindowPtr; cursorLoc: Point);
- { The mouse cursor is within the XWindow, perform any actions necessary,
- such as changing the cursor shape. }
- BEGIN
- { Setting the passFlag to true tells HyperCard that we would like it
- to handle changing the cursor to an arrow when the cursor is within
- the XWindow just as it does for the built-in windows. }
- paramPtr^.passFlag := TRUE;
- END; {HandleCursorWithin}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HandleHideShow(hideFlag: BOOLEAN);
- { An XCMD has called either the HideHCPalettes or ShowHCPalettes callbacks
- and our visible status has changed. An XCMD may wish to deallocate memory
- used for updating the XWindow if it knows it will be hidden for a period of
- time. An example usage would be if a significant amount of memory was
- required to maintain the contents of an XWindow. A script could call an
- XCMD to send the HidePalettes event when the user entered the paint tools
- so that the XCMD could free what memory it could to provide more memory
- for the paint buffers. }
- BEGIN
- END; {HandleHideShow}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE HandleEvents;
- { Handle events specific to our XWindow. HyperCard will only send events
- to the XCMD pertaining to windows it has opened. The XCMD, however,
- should not assume that it owns only one window. Subsequent calls to
- the XCMD to create the XWindow will result in one XCMD code segment
- owning multiple XWindows. This routine is similar to the main event loop
- of an application, all events dealing with the XWindows the XCMD has
- created will be sent here and dispatched to the appropriate routine to
- respond to them. }
- VAR
- myEventInfo: XWEventInfoPtr;
- window: WindowPtr;
- event: EventRecord;
- BEGIN
- myEventInfo := XWEventInfoPtr(paramPtr^.params[1]);
- window := myEventInfo^.eventWindow;
- event := myEventInfo^.event;
-
- CASE event.what OF
- nullEvt: ProcessIdle(window);
- xOpenEvt: HandleOpenEvent(window);
- updateEvt: UpdateXWindow(window);
- mouseDownEvt: HandleWindowClick(window, event);
- xHidePalettesEvt,
- xShowPalettesEvt: HandleHideShow(event.what = xHidePalettesEvt);
- xCloseEvt: CleanUpMemory(window);
- xCursorWithin: HandleCursorWithin(window, event.where);
- END; {case}
- END; {HandleEvents}
-
-
- { -------------------------------------------------------------------------- }
- PROCEDURE SetUpContents(whichWindow: WindowPtr);
- { Our window has been created via a call to the NewXWindow callback and is
- invisible. Now handle any initialization necessary for the XWindow such as
- calling NewControl, etc. }
- BEGIN
- END; {SetupContents}
-
-
- { -------------------------------------------------------------------------- }
- FUNCTION CorrectVersion: BOOLEAN;
- { This returns true if the version of HyperCard is >= minVersion. Very
- important for XCMDs that use callbacks specific to 1.1 or later versions
- of HyperCard IIGS. HyperCard IIGS 1.0 will execute a BRK and take a one-
- way trip to the monitor or debugger if an XCMD attempts an invalid callback
- number. HyperCard IIGS 1.1 calls the SysFail manager with the message,
- "Invalid callback attempted by XCMD" if a callback numbered greater than
- $38 is attempted, BTW. }
- CONST
- minVersion = '1.1';
- VAR
- tempHandle: Handle;
- tempStr: Str255;
- BEGIN
- tempHandle := EvalExpr('the version');
- ZeroToPas(tempHandle^, tempStr);
- MyDisposeHandle(tempHandle);
- CorrectVersion := tempStr >= minVersion;
- END; {CorrectVersion}
-
-
- BEGIN
- { The main routine of the XCMD. Most XWindow XCMDs will have fairly small
- main routine with the majority of the bulk of the XCMD in the routines
- dispatched to by the HandleEvents procedure. This main routine simply
- deals with calling HandleEvents, displaying Help or Copyright notices,
- and the initial creation of the XWindow. }
-
- { Get the memory ID to be used for all calls to the memory manager. This
- ID will be unique to each XWindow. }
- memoryID := paramPtr^.UserID;
-
- { If the paramCount is negative, we have been called in response to an event. }
- IF paramPtr^.paramCount < 0 THEN BEGIN
- HandleEvents;
- EXIT(XWindShell);
- END; {if}
-
- { Display help or copyright info in response to "?" or "!". }
- IF paramPtr^.paramCount = 1 THEN BEGIN
- ZeroToPas(paramPtr^.params[1]^, str);
- IF str = '!' THEN CommandInfo(CopyrightStr);
- IF str = '?' THEN CommandInfo(HelpStr);
- END; {if}
-
- { Make sure we are running at least version 1.1 of HyperCard IIGS. }
- IF NOT CorrectVersion THEN ReturnResult(WrongVersionStr);
-
- { Check for the desired number of parameters. XCMDs with optional
- parameters will need to check the paramCount for being within a
- certain range. Only scripting errors such as an invalid paramCount
- should generate a HyperTalk error. Other problems such as invalid or
- out-of-range data in the parameters should be handled by returning an
- appropriate error string the the result. }
- IF paramPtr^.paramCount <> 0 THEN HTError;
-
- { Here the XCMD should process any parameters required. See the other
- sample XCMDs for examples of using the ZeroToPas and other conversion
- callbacks to convert the zero-terminated input parameters into other
- forms. }
-
- { Create the XWindow initially invisible. We'll show it after we
- perform any needed initialization on it, such as creating controls, etc. }
- SetRect(windRect, LeftPos, TopPos, LeftPos + WindWidth, TopPos + WindHeight);
- xWindow := NewXWindow(windRect, WindTitle, FALSE, xWindoidStyle);
- IF xWindow = NIL THEN ReturnResult(CreateErrStr);
-
- { Create the contents for the window }
- SetPort(xWindow);
- SetUpContents(xWindow);
-
- { Display the window. This will generate an update event which will be sent
- immediately following the xOpenEvt. }
- ShowWindow(xWindow);
- END; {XWindShell}
-
- END. { of the dummy unit }